﻿using System;
using System.Collections.Generic;
using System.Linq;
using Cms.Application.Admin.Views;
using Cms.Data;
using Cms.Domain;
using Cms.Domain.Comparers;
using Cms.Domain.RepositoryInterfaces;

namespace Cms.Application.Admin.Presenters
{
    public class EditContentPreviewPresenter : BasePresenter
    {
        private readonly IEditContentPreviewView _view;
        protected Administrator _administrator;

        public EditContentPreviewPresenter(IEditContentPreviewView view)
            : this(view, new RepositoryFactory())
        {
        }

        public EditContentPreviewPresenter(IEditContentPreviewView view, IRepositoryFactory repositoryFactory)
            : base(view, repositoryFactory)
        {
            _view = view;
            _administrator = AdministratorRepository.GetAdministrator(_view.AdministratorID);
            if (!_administrator.HasPermission.EditContentPreview)
                _view.RedirectToPermissionDeniedPage();
        }
        
        public void SetLocales()
        {
            _view.SetLocales(_administrator.CurrentSite.Locales);
        }

        public void SetHeading()
        {
            if (_view.ContentID > 0)
            {
                Content content = ContentRepository.GetContent(_view.ContentID);
                if (content != null)
                    _view.SetHeading(content.Name);
            }
            else if (_view.VersionID > 0)
            {
                ContentTranslationVersion ctv = ContentRepository.GetContentTranslationVersion(_view.VersionID);
                if (ctv != null)
                    _view.SetHeading(ctv.Translation.Content.Name);
            }
        }

        public virtual void Initialize()
        {
            _view.SetMasterTemplates(_administrator.CurrentSite.MasterTemplates);
            if (_administrator.CurrentSite.DefaultMasterTemplate != null)
                _view.SelectedMasterTemplateID = _administrator.CurrentSite.DefaultMasterTemplate.ID;
            if (_administrator.CurrentSiteLocale != null)
                _view.SelectedLocaleID = _administrator.CurrentSiteLocale.ID;
            if (_view.ContentID < 0 && _view.VersionID > 0)
            {
                ContentTranslationVersion ctv = ContentRepository.GetContentTranslationVersion(_view.VersionID);
                _view.SetContentID(ctv.Translation.Content.ID);
            }
            SetVersions();
            if (_view.ContentID <= 0)
                return;
            Content content = ContentRepository.GetContent(_view.ContentID);
            if (content.Translations.ContainsKey(_view.SelectedLocaleID))
                _view.SelectedVersionID = content.Translations[_view.SelectedLocaleID].Versions.Last().ID;
        }
        
        public virtual int GetContentID()
        {
            return _view.ContentID > 0 ? _view.ContentID : -2;
        }
        
        public virtual int GetMasterTemplateID()
        {
            Content content = ContentRepository.GetContent(_view.ContentID);
            return content != null
                       ? content.Site.DefaultMasterTemplate.ID
                       : _administrator.CurrentSite.DefaultMasterTemplate.ID;
        }
        
        public void SaveSelectedLocale()
        {
            _administrator.CurrentSiteLocale = LocaleRepository.GetLocale(_view.SelectedLocaleID);
            AdministratorRepository.SaveAdministrator(_administrator);
        }
        
        public void SetVersions()
        {
            Content content = ContentRepository.GetContent(_view.ContentID);
            if (content != null && content.Translations.ContainsKey(_view.SelectedLocaleID))
            {
                int publishedVersionID = -1;
                if (content.Translations[_view.SelectedLocaleID].PublishedVersion != null)
                    publishedVersionID = content.Translations[_view.SelectedLocaleID].PublishedVersion.ID;
                IList<ContentTranslationVersion> versions = content.GetVersions(_view.SelectedLocaleID);
                _view.SetVersions(versions, publishedVersionID);
                List<ScheduledPublishing> scheduledPublishings =
                    versions.SelectMany(ctv => ctv.ScheduledPublishings).ToList();
                scheduledPublishings.Sort(new ScheduledPublishingComparer(SortDirection.Ascending));
                _view.SetScheduledPublishings(scheduledPublishings);
            }
            else
            {
                _view.SetVersions(new List<ContentTranslationVersion>(), -1);
                _view.SetScheduledPublishings(new List<ScheduledPublishing>());
            }
        }
        
        public virtual void Save()
        {
            if (!IsValid)
                return;
            Content content;
            if (_view.ContentID == -1)
            {
                content = new Content { Site = _administrator.CurrentSite };
            }
            else
            {
                content = ContentRepository.GetContent(_view.ContentID);
            }
            //ContentRepository.SaveContent(content);
        }
        
        public void Publish()
        {
            Content content = ContentRepository.GetContent(_view.ContentID);
            ContentTranslationVersion ctv = ContentRepository.GetContentTranslationVersion(_view.SelectedVersionID);
            if (ctv == null)
                return;
            ctv.Publish();
            SiteRepository.SaveSite(_administrator.CurrentSite);
            SetVersions();
            _view.SelectedVersionID = ctv.ID;
        }

        public void SchedulePublishing(int contentTranslationVersionID, DateTime scheduledPublishingDateTime)
        {
            ContentTranslationVersion ctv = ContentRepository.GetContentTranslationVersion(contentTranslationVersionID);
            if (ctv == null)
                return;
            var scheduledPublishing = new ScheduledPublishing
                                          {
                                              Timestamp = scheduledPublishingDateTime.Ticks.ToString(),
                                              ContentTranslationVersion = ctv,
                                              Description = null
                                          };
            ctv.ScheduledPublishings.Add(scheduledPublishing);
            SiteRepository.SaveSite(_administrator.CurrentSite);
            SetVersions();
        }
        
        public void DeleteScheduledPublishing(int id)
        {
            ContentRepository.DeleteScheduledPublishing(id);
            SetVersions();
        }
    }
}